using System;
using System.Text;
using System.Collections;
using System.IO;
using System.Collections.Specialized;
using MM7.MIME.Encoding;

namespace MM7.MIME
{
	internal class MimeContainer
	{
		private MimeBoundary _mimeboundary=null;
		private ArrayList _attachments=new ArrayList();
		private ArrayList _mimecontainers=new ArrayList();
		private ContainerType _contenttype=ContainerType.mixed;
		private bool _istoplevel=true;
		private MIMEType _type = MIMEType.xml;
		private string _start = null;
		private string _contentid = Guid.NewGuid().ToString("N");

		private MIMEEncoding _encoding = MIMEEncoding.EightBitEncoding;

		public MIMEEncoding Encoding 
		{
			get {return _encoding;}
			set {_encoding=value;}
		}

		public ContainerType ContentType
		{
			get{return _contenttype;}
			set{_contenttype=value;}
		}

		public string Start
		{
			get{return _start;}
		}

		public string ContentID
		{
			get{return _contentid;}
		}

		public MimeContainer(MimeBoundary mimeboundary, bool istoplevel)
		{
			this._mimeboundary=mimeboundary;
			this._istoplevel=istoplevel;
		}

		public void AddAttachment(Attachment attachment)
		{
			_attachments.Add(attachment);
		}

		public void AddPreAttachment(Attachment attachment)
		{
			_contenttype=ContainerType.related;
			_start = attachment.ContentId;
			_type = attachment.ContentType;
			_attachments.Add(attachment);
		}

		public void AddMimeContainer(MimeContainer mimecontainer) 
		{
			_mimecontainers.Add(mimecontainer);
		}

		private byte[] EncodeHeader()
		{
			StringBuilder sb=new StringBuilder();
			sb.Append("Content-Type: "+_contenttype.ToString()+";boundary=\""+_mimeboundary.BoundaryString+"\";type=\""+_type.ToString()+"\"");
			if (_start != null)
			{
				sb.Append(";start=\"<"+_start+">\"");
			}
			sb.Append(Attachment.ENDOFLINE);
			sb.Append(Attachment.CONTENTID+": <" + _contentid + ">" + Attachment.ENDOFLINE);
			sb.Append(Attachment.CONTENTTRANSFERENCODING+": 8bit"+Attachment.ENDOFLINE);
			sb.Append(Attachment.ENDOFLINE);
			string a = sb.ToString();
			System.Text.Encoding sss = System.Text.Encoding.GetEncoding("ISO8859-1");
			byte[] d = sss.GetBytes(a);
			return d;
		}

		public byte[] Encode() 
		{
			MemoryStream stream = new MemoryStream();
			if (_istoplevel)
			{
				byte[] a = EncodeHeader();
				stream.Write(a, 0, a.Length);
			}

			foreach (Attachment attachment in _attachments) 
			{
				StringBuilder sb=new StringBuilder();
				sb.Append(_mimeboundary.BoundaryStringStart+Attachment.ENDOFLINE);
				string a = sb.ToString();
				System.Text.Encoding sss = System.Text.Encoding.GetEncoding("ISO8859-1");
				byte[] d = sss.GetBytes(a);
				stream.Write(d, 0, d.Length);

				byte[] b = attachment.Encode();
				stream.Write(b, 0, b.Length);
			}

			foreach (MimeContainer mimecontainer in _mimecontainers) 
			{
				StringBuilder sb=new StringBuilder();
				sb.Append(_mimeboundary.BoundaryStringStart+Attachment.ENDOFLINE);
				string a = sb.ToString();
				System.Text.Encoding sss = System.Text.Encoding.GetEncoding("ISO8859-1");
				byte[] d = sss.GetBytes(a);
				stream.Write(d, 0, d.Length);

				byte[] b = mimecontainer.Encode();
				stream.Write(b, 0, b.Length);		
			}

			StringBuilder sb1 =new StringBuilder();
			sb1.Append(_mimeboundary.BoundaryStringEnd+Attachment.ENDOFLINE);
			string a1 = sb1.ToString();
			System.Text.Encoding sss1 = System.Text.Encoding.GetEncoding("ISO8859-1");
			byte[] d1 = sss1.GetBytes(a1);
			stream.Write(d1, 0, d1.Length);

			byte[] buffer = new byte[stream.Length];
			stream.Seek(0, SeekOrigin.Begin);
			stream.Read(buffer, 0, buffer.Length);
			stream.Close();
			return buffer;
		}
/*
		public void Decode(NameValueCollection headers, byte[] buffer)
		{
			NameValueCollection outHeaders;
			ParseHead(headers, out outHeaders);
			string contentType = outHeaders.Get("content-type");
			if (contentType == null) contentType = "";
			string contentID = outHeaders.Get("contentid");
			if (contentID == null) contentID = "";
			string contentTransferEncoding = outHeaders.Get("content-transfer-encoding");
			if (contentTransferEncoding == null) contentTransferEncoding = "";
			string boundary = outHeaders.Get("boundary");
			if (boundary == null) boundary = "";
			string start = outHeaders.Get("start");
			if (start == null) start = "";
			string type = outHeaders.Get("type");
			if (type == null) type = "";
			if (contentType.Equals("multipart/related")) _contenttype = MimeType.related;
			else if (contentType.Equals("multipart/related")) _contenttype = MimeType.mixed;
			else _contenttype = MimeType.xml;
			if (string.Compare("text/xml", type, true) == 0)
			{
				_type = AttachmentType.xml;
			}
			else if(string.Compare("application/smil", type, true) == 0)
			{
				_type = AttachmentType.smil;
			}
			else
			{
				_type = AttachmentType.stream;
			}
			_start = start;
			_contentid = contentID;
			_mimeboundary = new MimeBoundary();
			_mimeboundary.BoundaryString =boundary;
		}
*/
	}

	public class ContainerType
	{
		private string _type = null;

		public static ContainerType related
		{
			get{ return new ContainerType("multipart/related");}
		}

		public static ContainerType mixed
		{
			get{ return new ContainerType("multipart/mixed");}
		}

		public static ContainerType xml
		{
			get{ return new ContainerType("text/xml");}
		}

		public ContainerType(string type)
		{
			if (string.Compare(type, "multipart/related", true) == 0)
			{
				_type = "multipart/related";
			}
			else if(string.Compare(type, "multipart/mixed", true) == 0)
			{
				_type = "multipart/mixed";
			}
			else if(string.Compare(type, "text/xml", true) == 0)
			{
				_type = "text/xml";
			}
			else
			{
				_type = "text/html";
			}
		}

		public override string ToString()
		{
			return _type;
		}
	}

}
